package com.neusoft.neuiotms.dcom.task;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neusoft.bizcore.cache.utils.DateUtil;
import com.neusoft.bizcore.notice.notification.dto.NoticeDingDTO;
import com.neusoft.bizcore.notice.notification.dto.NoticeRecordDTO;
import com.neusoft.bizcore.notice.notification.dto.NoticeRecordSystemDTO;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.neuiotms.dcom.constants.DCOMConstants;
import com.neusoft.neuiotms.dcom.model.Institutions;
import com.neusoft.neuiotms.dcom.model.ResidentUser;
import com.neusoft.neuiotms.dcom.model.enums.InsuranceReportTaskStatus;
import com.neusoft.neuiotms.dcom.model.enums.InsuranceTaskStatus;
import com.neusoft.neuiotms.dcom.model.insurance.InsuranceInspectionTask;
import com.neusoft.neuiotms.dcom.model.insurance.InsuranceReportTask;
import com.neusoft.neuiotms.dcom.repository.InstitutionsRepository;
import com.neusoft.neuiotms.dcom.repository.insurance.InsuranceInspectionTaskRepository;
import com.neusoft.neuiotms.dcom.repository.insurance.InsuranceReportTaskRepository;
import com.neusoft.neuiotms.micro.notice.NoticeMicroService;

import lombok.extern.slf4j.Slf4j;

/**
 * 用来设置重保服务任务状态 1.更新重保巡检、每日上报、服务总结, 2.根据单位进行相对应的一线运维工程师通知
 */

@Slf4j
@Component
public class InsuranceRegisterTask {

    @Autowired
    private InsuranceInspectionTaskRepository inspectionRepository;
    @Autowired
    private InsuranceReportTaskRepository reportRepository;
    @Autowired
    private InstitutionsRepository institutionsRepository;
    @Autowired
    private NoticeMicroService noticeMicroService;

    //0 0/5 * * * ?    0 0 0 * * ?
    @Scheduled(cron = "0 0 1 * * ?")
    protected void executeInternal() {
        InsuranceRegisterTask.log.info("定时--开始--检查每个重保服务任务的状态");
        // 重保巡检与每日上报
        final Searchable inspectionSearchable = new Searchable();
        //final Date dayStart = DateUtil.getStartTimeOfDate(new Date());
        final Long dayStart = DateUtil.getStartTimeOfDate(new Date()).getTime();

        inspectionSearchable.put("startTime", dayStart);
        inspectionSearchable.put("endTime", dayStart);
        inspectionSearchable.put("status", InsuranceTaskStatus.notActive);
        final List<InsuranceInspectionTask> notActiveInspectionLists =
                this.inspectionRepository.index(inspectionSearchable);
        final Searchable reportSearchable = new Searchable();
        reportSearchable.put("startTime", dayStart);
        reportSearchable.put("endTime", dayStart);
        reportSearchable.put("status", InsuranceReportTaskStatus.notActive);
        final List<InsuranceReportTask> notActiveReportLists = this.reportRepository.index(reportSearchable);

        // 重保巡检
        if (null != notActiveInspectionLists) {
            // 改变状态
            final List<InsuranceInspectionTask> pendingInspectionLists = notActiveInspectionLists.stream().map(p -> {
                p.setStatus(InsuranceTaskStatus.pending);
                return p;
            }).collect(Collectors.toList());

            this.inspectionRepository.saveAll(pendingInspectionLists);

            // 获取单位发送单位下的所有一线人员通知
            final List<String> unitCodes =
                    notActiveInspectionLists.stream().map(InsuranceInspectionTask::getUnitCode)
                            .collect(Collectors.toList());
            unitCodes.forEach(e -> {
                final Institutions institutionsModel = this.institutionsRepository.findByCode(e);
                final List<String> userNames = institutionsModel.getResidents().stream().map(ResidentUser::getUsername)
                        .collect(Collectors.toList());
                this.sendMessage(userNames, "重保服务巡检");
            });
        }

        // 每日上报
        if (null != notActiveReportLists) {
            // 改变状态
            final List<InsuranceReportTask> pendingReportLists = notActiveReportLists.stream().map(p -> {
                p.setStatus(InsuranceReportTaskStatus.toBeReported);
                return p;
            }).collect(Collectors.toList());

            this.reportRepository.saveAll(pendingReportLists);

            // 获取单位发送单位下的所有一线人员通知
            final List<String> unitCodes =
                    notActiveReportLists.stream().map(InsuranceReportTask::getUnitCode)
                            .collect(Collectors.toList());
            unitCodes.forEach(e -> {
                final Institutions institutionsModel = this.institutionsRepository.findByCode(e);
                final List<String> userNames = institutionsModel.getResidents().stream().map(ResidentUser::getUsername)
                        .collect(Collectors.toList());
                this.sendMessage(userNames, "每日上报");
            });
        }

        InsuranceRegisterTask.log.info("定时--结束--检查每个重保服务任务的状态");
    }

    /**
     * 人员通知
     */
    private void sendMessage(final List<String> users, final String registerType) {
        InsuranceRegisterTask.log.info("重保服务一线运维工程师" + registerType + "通知开始");
        try {
            if (!users.isEmpty()) {
                final NoticeRecordDTO notice = new NoticeRecordDTO();
                notice.setTitle("重保服务任务");
                notice.setType(Lists.newArrayList(DCOMConstants.INFORM_TYPE_NOTICE));
                notice.setAppCode("dcom");
                final NoticeRecordSystemDTO sys = new NoticeRecordSystemDTO();
                sys.setContent("您有" + registerType);
                sys.setNoticeType("重保服务任务：" + registerType);
                //                sys.setNoticeRoute("registerTask");
                final JSONObject info = new JSONObject();
                sys.setBusinessInfo(info.toString());
                sys.setUsers(users);
                notice.setSystem(sys);

                // 添加钉钉通知
                final NoticeDingDTO toDing = new NoticeDingDTO();
                toDing.setMsgtype("link");
                toDing.setUsers(users);
                final Map<String, String> linkParams = Maps.newHashMap();
                linkParams.put("messageUrl", "eapp://pages/inspection/table/table?type=insurance");
                linkParams.put("picUrl", "@lALPDeRETJL6S3XMtMy0");
                linkParams.put("title", "重保巡检任务");
                linkParams.put("text", "您有" + registerType);
                toDing.setJsonBody(JsonUtils.pojoToJson(linkParams));
                notice.setDing(toDing);

                this.noticeMicroService.createNotification(JsonUtils.pojoToJson(notice));
            } else {
                InsuranceRegisterTask.log.error("重保服务通知用户为null");
            }
        } catch (final Exception e) {
            e.printStackTrace();
            InsuranceRegisterTask.log.error("重保服务通知异常" + e.getMessage());
        }
        InsuranceRegisterTask.log.info("重保服务一线运维工程师" + registerType + "通知结束");
    }

}
